package controller;

import controller.dialog.DialogIntecao;
import controller.dialog.DialogLancarDados;
import controller.dialog.DialogOferta;
import drag.Engenheiro;
import interfaces.ControlaJogo;
import java.net.URL;
import java.rmi.RemoteException;
import java.text.DecimalFormat;
import java.util.List;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Rectangle2D;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Screen;
import model.GridPeoes;
import model.Peao;
import model.Pessa;
import model.TAGS;
import model.Tabuleiro;

/**
 * Controller do tabulleiro. Essa classe e geral pois tem a finalidade pivo de disignar as funcionalidades.
 * A classe também implementa o contralaJogo sendo assim recebe as notificações do observer vindo do servidor.
 * @author Adriano
 */
public class TabuleiroController implements Initializable, ControlaJogo {

    @FXML
    private GridPane grid;//Grid que sustenta os campos
    @FXML
    private AnchorPane painel;//Painel geral do tabuleiro
    @FXML
    private Label labelMoney;//Label que exibe a quantidade monetária
    @FXML
    private  TextArea message;//Label que exibe mensagens de notificação
    @FXML
    private Button btLancar;//Button de lançar dados
    @FXML
    private GridPane gridPeoes;//Grid que exibe a lista de jogadores com seu respectivos nome e peão
    @FXML
    private ImageView imageCasa;//Imagem da casa
    @FXML
    private ImageView imageHotel;//Imagem do hotel
    @FXML
    private Label moneyCasa;//Valor da casa
    @FXML
    private Label moneyHotel;//Valor do hotel

    public TabuleiroController() {
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        ControllerObserver.getControllerObserver().setControlaJogo(this);

        Screen screen = Screen.getPrimary();
        Rectangle2D bounds = screen.getVisualBounds();

        painel.setPrefWidth(bounds.getWidth());
        painel.setPrefHeight(bounds.getHeight());

        grid.setLayoutX(5);
        grid.setLayoutY(5);
        grid.setPrefSize(bounds.getWidth() - 10, bounds.getHeight()-190);

        labelMoney.setLayoutY(bounds.getHeight()-190);
        btLancar.setLayoutY(bounds.getHeight()-190);
        btLancar.setVisible(false);
        
        message.setLayoutY(bounds.getHeight() - 190 + 50);

        gridPeoes.setLayoutX(bounds.getWidth() - 160);
        gridPeoes.setLayoutY(bounds.getHeight() - 190);
        update();

        Engenheiro engenheiro = new Engenheiro(imageCasa, "casa");
        imageCasa.setOnDragDetected(engenheiro.getDragDetected());
        imageCasa.setOnDragOver(engenheiro.getDragDone());
        imageCasa.setLayoutY(bounds.getHeight() - 190);

        engenheiro = new Engenheiro(imageHotel, "hotel");
        imageHotel.setOnDragDetected(engenheiro.getDragDetected());
        imageHotel.setOnDragOver(engenheiro.getDragDone());
        imageHotel.setLayoutY(bounds.getHeight()-200);

        moneyCasa.setLayoutY(bounds.getHeight()-190 + 50);
        moneyHotel.setLayoutY(bounds.getHeight()-190 + 50);
    }

    /**Método que atualiza o tabuleiro*/
    private void update() {
        Screen screen = Screen.getPrimary();
        Rectangle2D bounds = screen.getVisualBounds();
        int cot = 0;
        painel.getChildren().remove(grid);
        grid = new GridPane();
        grid.setLayoutX(5);
        grid.setLayoutY(5);
        grid.setPrefSize(bounds.getWidth(), bounds.getHeight()-190);
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 10; j++) {
                if (Tabuleiro.getTabuleiro().getQuadros().size() > cot) {
                    grid.add(Tabuleiro.getTabuleiro().getQuadros().get(cot), j, i);
                }
                cot++;
            }
        }
        painel.getChildren().add(grid);
    }

    @Deprecated
    public void liberarTela(boolean status) throws RemoteException {
    }

    @Deprecated
    public void jogadoresLista(String jogadores) throws RemoteException {
    }

    @Deprecated
    public void escreveTeste(final String str) throws RemoteException {
    }

    @Override
    public void listaPeao(final List<Peao> lista) throws RemoteException {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                Tabuleiro.getTabuleiro().clear();
                for (Peao peao : lista) {
                    GridPeoes gp = new GridPeoes(gridPeoes, lista);
                    Pessa p = new Pessa(peao.getCor());
                    Tabuleiro.getTabuleiro().getQuadros().get(peao.getPositon()).addPeao(p);
                    Tabuleiro.getTabuleiro().setDodo(peao.getListaCampos(), peao.getNome());
                    if (peao.getNome().equals(TAGS.NAME)) {
                        TAGS.POSITION = peao.getPositon();
                        DecimalFormat format = new DecimalFormat("0.00");
                        labelMoney.setText("R$: " + format.format(peao.getDinheiros()));
                    }
                }
                update();
            }
        });
    }

    @Override
    public void vesdeJogada(final String jogadorNome) throws RemoteException {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                if (jogadorNome.equals(TAGS.NAME)) {
                    //Abilitar o button de lançar os dados
                    btLancar.setVisible(true);
                    mensagem("Lance os dados");
                }
            }
        });
    }

    @Override
    public void mensagem(final String nome, final String mensagem) throws RemoteException {
        if (nome.equals(TAGS.NAME)) {
            mensagem(mensagem);
        }
    }

    @Override
    public void comprar(final String nome, final String campo) throws RemoteException {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                if (nome.equals(TAGS.NAME)) {
                    //Exibir o dialog para realizar uma oferta
                    DialogOferta.getIntancia().show(campo);
                }
            }
        });
    }

    /**Listener do button lançar dados*/
    public void lancar(ActionEvent evnt) {
        DialogLancarDados.getIntancia().show();
        btLancar.setVisible(false);
    }

    @Override
    public void intensaoCompra(final String jogadorDono, final String jogadorInteresado, final String campo, final String valor) throws RemoteException {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                if (jogadorDono.equals(TAGS.NAME)) {
                    //exibir o dialogo de uma oferta
                    DialogIntecao.getIntancia().show(jogadorInteresado, Integer.parseInt(campo.trim()), valor);
                }
            }
        });
    }
    
    /**Método que faz o controlle das mensagens de notificação*/
    private void mensagem(final String mensagem) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                message.setText(message.getText()+"\n"+mensagem);
                message.positionCaret(Integer.MAX_VALUE);
            }
        });
    }
}